package server;

import shared.PlayerPortfolio;
import server.ProfessionFactory.profession_type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Random;

/**
 * ProfessionFactory initializer
 * @author Joel Garboden
 * Contains the definitions for individual professions inside a wrapper class
 */
public class ProfessionFactory
{
  public static final double BASE_TAX_RATE = 0.095;
  public static final double BASE_HOUSE_RATE = 0.089;
  public static final double BASE_CAR_RATE = 0.089;
  public static final double BASE_CARD_RATE = 0.089;
  public static final double BASE_LOAN_RATE = 0.089;
  public static final int BASE_LIVING_EXPENSE = 200;

  public static final double GENERIC_CARD_INTEREST_CHANGE = 0.05;

  public static final int MINOR_DEMOTION_PROMOTION = 1;
  public static final int MODERATE_DEMOTION_PROMOTION = 5;
  public static final int MAJOR_DEMOTION_PROMOTION = 10;
  public static final int MASSIVE_DEMOTION_PROMOTION = 20;

  /**
   *
   */
  public enum profession_type {PILOT, ENTREPENEUR};
//                                DOCTOR, ENGINEER, JANITOR,
//                               LAWYER, MECHANIC, NURSE, COP, SECRETARY, TEACHER,
//                               DRIVER};

  private static HashMap<profession_type, Profession> professionList;

  public ProfessionFactory()
  {
    professionList = new HashMap<>();
    professionList.put(profession_type.PILOT, new Pilot());
    professionList.put(profession_type.ENTREPENEUR, new Entrepreneur());
    /* //TODO implement the rest of the professions
    professionList.add(new Doctor());
    professionList.add(new Engineer());
    professionList.add(new Janitor());
    professionList.add(new Mechanic());
    professionList.add(new Nurse());
    professionList.add(new Cop());
    professionList.add(new Secretary());
    professionList.add(new Teacher());
    professionList.add(new Driver());
    */
  }

  /**
   *
   * @return
   */
  public static profession_type getRandomProfessionID()
  {
    Random r = new Random();

    int randomProf = r.nextInt(professionList.size());

    return profession_type.values()[randomProf];
  }

  public abstract class Profession
  {
    /**
     *
     * @param portfolio
     */
    public abstract void setProfession(PlayerPortfolio portfolio);
  }

  /**
   *
   * @param profType
   * @param playerName
   * @return profession index is (in)valid
   */
  public PlayerPortfolio makePortfolioFor(profession_type profType, String playerName)
  {
    PlayerPortfolio portfolio = new PlayerPortfolio(playerName);
    Profession prof = (Profession) professionList.get(profType);
    prof.setProfession(portfolio);
    return portfolio;
  }

  /**
   *
   */
  public class Pilot extends Profession
  {
    /**
     *
     * @param portfolio
     */
    @Override
    public void setProfession(PlayerPortfolio portfolio)
    {
      portfolio.profession = "Pilot";
      portfolio.balanceChange(3000);
      //TODO verify calculation matches
      //portfolio.paycheckAmount = 2600; 
      portfolio.payWeek = 1;

      portfolio.salary = 9500;

      portfolio.monthlyTaxes = 2350;
      portfolio.taxInterestRate = BASE_TAX_RATE;

      portfolio.monthlyHousePayment = 1330;
      portfolio.houseInterestRate = BASE_HOUSE_RATE;

      portfolio.monthlySchoolPayment = 0;
      portfolio.monthlyCarPayment = 300;
      portfolio.carInterestRate = BASE_CAR_RATE;

      portfolio.monthlyCardPayment = 660;
      portfolio.cardInterestRate = BASE_CARD_RATE;

      portfolio.monthlyLoanInterestRate = BASE_LOAN_RATE;

      portfolio.weeklyRetailPayment = 50;
      portfolio.weeklyMiscPayment = 2210;

      portfolio.monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

      portfolio.weeklyCostPerChild = 480;

      portfolio.remainingHousePayment = 143000;
      portfolio.remainingSchoolPayment = 0;
      portfolio.remainingCarPayment = 15000;
      portfolio.chargeChange(22000, 0.0); //remainingCardPayment

      portfolio.prof_ID = profession_type.PILOT;
      portfolio.performanceSteps = Arrays.asList(10, 20, 30, 60, 120);
    }
  }

  /**
   * Initialization data for Business Entrepreneur profession
   */
  public class Entrepreneur extends Profession
  {
    /**
     *
     * @param portfolio
     */
    @Override
    public void setProfession(PlayerPortfolio portfolio)
    {
      portfolio.profession = "Entrepeneur";
      portfolio.balanceChange(2070);
      //portfolio.paycheckAmount = 1670;
      portfolio.payWeek = 1;

      portfolio.salary = 4600;

      portfolio.monthlyTaxes = 910;
      portfolio.taxInterestRate = BASE_TAX_RATE;

      portfolio.monthlyHousePayment = 700;
      portfolio.houseInterestRate = BASE_HOUSE_RATE;

      portfolio.monthlySchoolPayment = 60;
      portfolio.monthlyCarPayment = 120;
      portfolio.carInterestRate = BASE_CAR_RATE;

      portfolio.monthlyCardPayment = 90;
      portfolio.cardInterestRate = BASE_CARD_RATE;

      portfolio.weeklyRetailPayment = 50;
      portfolio.weeklyMiscPayment = 1000;

      portfolio.weeklyCostPerChild = 240;

      portfolio.monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

      portfolio.remainingHousePayment = 75000;
      portfolio.remainingSchoolPayment = 12000;
      portfolio.remainingCarPayment = 6000;
      portfolio.chargeChange(3000, 0.0); //remainingCardPayment

      portfolio.prof_ID = profession_type.ENTREPENEUR;
      portfolio.performanceSteps = Arrays.asList(10, 30, 60, 120);      
    }
  }

  //TODO portfolio.performanceSteps = Arrays.asList(10, 20, 30, 60, 120); to all professions

  /**
   * Initialization data for Doctor profession
   */
  /*
  public void setAsDoctor()
  {
    professionName = "Doctor";
    cash = 3950;
    paycheckAmount = 3550;
    payWeek = 1;

    salary = 13200;

    monthlyTaxes = 3420;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 1900;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 750;
    monthlyCarPayment = 380;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 270;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 2880;

    weeklyCostPerChild = 640;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 202000;
    remainingSchoolPayment = 150000;
    remainingCarPayment = 19000;
    remainingCardPayment = 9000;

    prof_ID = profession_type.DOCTOR;
    performanceSteps = Arrays.asList(10, 20, 30, 60, 120);
  }

  /**
   * Initialization data for Engineer profession
   */
  /*
  public void setAsEngineer()
  {
    professionName = "Engineer";
    cash = 2090;
    paycheckAmount = 1690;
    payWeek = 1;

    salary = 4900;

    monthlyTaxes = 1000;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 700;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 60;
    monthlyCarPayment = 140;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 120;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 1090;

    weeklyCostPerChild = 250;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 75000;
    remainingSchoolPayment = 12000;
    remainingCarPayment = 7000;
    remainingCardPayment = 4000;

    prof_ID = profession_type.ENGINEER;
  }

  /**
   * Initialization data for Janitor profession
   */
  /*
  public void setAsJanitor()
  {
    professionName = "Janitor";
    cash = 1110;
    paycheckAmount = 650;
    payWeek = 1;

    salary = 1600;

    monthlyTaxes = 280;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 200;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 0;
    monthlyCarPayment = 60;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 60;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 300;

    weeklyCostPerChild = 70;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 20000;
    remainingSchoolPayment = 0;
    remainingCarPayment = 4000;
    remainingCardPayment = 2000;

    prof_ID = profession_type.JANITOR;
  }

  /**
   * Initialization data for Lawyer profession
   */
  /*
  public void setAsLawyer()
  {
    professionName = "Lawyer";
    cash = 2480;
    paycheckAmount = 2080;
    payWeek = 1;

    salary = 7500;

    monthlyTaxes = 1830;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 1100;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 390;
    monthlyCarPayment = 220;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 180;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 1650;

    weeklyCostPerChild = 380;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 115000;
    remainingSchoolPayment = 78000;
    remainingCarPayment = 11000;
    remainingCardPayment = 6000;

    prof_ID = profession_type.LAWYER;
  }

  /**
   * Initialization data for Mechanic profession
   */
  /*
  public void setAsMechanic()
  {
    professionName = "Mechanic";
    cash = 1390;
    paycheckAmount = 720;
    payWeek = 1;

    salary = 2000;

    monthlyTaxes = 360;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 300;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 0;
    monthlyCarPayment = 60;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 60;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 450;

    weeklyCostPerChild = 110;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 31000;
    remainingSchoolPayment = 0;
    remainingCarPayment = 3000;
    remainingCardPayment = 2000;

    prof_ID = profession_type.MECHANIC;
  }

  /**
   * Initialization data for Nurse profession
   */
  /*
  public void setAsNurse()
  {
    professionName = "Nurse";
    cash = 1700;
    paycheckAmount = 1120;
    payWeek = 1;

    salary = 3100;

    monthlyTaxes = 600;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 400;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 30;
    monthlyCarPayment = 100;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 90;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 710;

    weeklyCostPerChild = 170;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 47000;
    remainingSchoolPayment = 6000;
    remainingCarPayment = 5000;
    remainingCardPayment = 3000;

    prof_ID = profession_type.NURSE;
    }

  /**
   * Initialization data for Police Officer profession
   */
  /*
  public void setAsPoliceOfficer()
  {
    /*
    professionName = "Police Officer";
    cash = 1640;
    paycheckAmount = 1120;
    payWeek = 1;

    salary = 3000;

    monthlyTaxes = 580;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 400;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 0;
    monthlyCarPayment = 100;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 60;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 690;

    weeklyCostPerChild = 160;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 46000;
    remainingSchoolPayment = 0;
    remainingCarPayment = 5000;
    remainingCardPayment = 2000;

    prof_ID = profession_type.COP;
  }

  /**
   * Initialization data for Secretary profession
   */
    /*
  public void setAsSecretary()
  {
    professionName = "Secretary";
    cash = 1590;
    paycheckAmount = 880;
    payWeek = 1;

    salary = 2500;

    monthlyTaxes = 460;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 400;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 0;
    monthlyCarPayment = 80;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 60;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 570;

    weeklyCostPerChild = 140;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 38000;
    remainingSchoolPayment = 0;
    remainingCarPayment = 4000;
    remainingCardPayment = 2000;

    prof_ID = profession_type.SECRETARY;
  }

  /**
   * Initialization data for Teacher profession
   */
    /*
  public void setAsTeacher()
  {
    professionName = "Teacher";
    cash = 1510;
    paycheckAmount = 1110;
    payWeek = 1;

    salary = 3300;

    monthlyTaxes = 630;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 500;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 60;
    monthlyCarPayment = 100;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 90;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 760;

    weeklyCostPerChild = 180;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 50000;
    remainingSchoolPayment = 12000;
    remainingCarPayment = 5000;
    remainingCardPayment = 3000;

    prof_ID = profession_type.TEACHER;
  }

  /**
   * Initialization data for Truck Driver profession
   */
    /*
  public void setAsTruckDriver()
  {
    professionName = "Truck Driver";
    cash = 1630;
    paycheckAmount = 880;
    payWeek = 1;

    salary = 2500;

    monthlyTaxes = 460;
    taxInterestRate = BASE_TAX_RATE;

    monthlyHousePayment = 400;
    houseInterestRate = BASE_HOUSE_RATE;

    monthlySchoolPayment = 0;
    monthlyCarPayment = 80;
    carInterestRate = BASE_CAR_RATE;

    monthlyCardPayment = 60;
    cardInterestRate = BASE_CARD_RATE;

    weeklyRetailPayment = 50;
    weeklyMiscPayment = 570;

    weeklyCostPerChild = 480;

    monthlyLivingExpensePayment = BASE_LIVING_EXPENSE;

    remainingHousePayment = 143000;
    remainingSchoolPayment = 0;
    remainingCarPayment = 15000;
    remainingCardPayment = 22000;

    prof_ID = profession_type.DRIVER;
  }
*/
}